/*
 * dsmReleaser.cpp
 *
 *  Created on: Dec 15, 2013
 *      Author: m
 */

#include <cstring>
#include "DSMComun.h"
#include "SharedMemory2.h"
#include "MessageQueue.h"
#include "ColaRemotaTransmisor.h"
#include "ColaRemotaReceptor.h"
#include "CPrinter.h"
#include "StringUtils.h"
#include "Robot11AProductor.h"
#include "Cinta15.h"
#include "Cinta13B.h"
#include "Cinta13A.h"
#include "Robot11BProductor.h"
#include "Robot14Consumidor.h"
#include "Robot14Productor.h"
#include "Robot16Consumidor.h"
#include "../../middleware/MiddlewareCommon.h"
#include "../../middleware/CommunicationPrimerCinta.h"
#include "../../middleware/CommunicationRobotPiezas.h"
#include "../../middleware/CommunicationRobot12.h"
#include "../../middleware/CommunicationRobot11.h"
#include "../../middleware/CommunicationRobot5.h"

using ipc::MessageQueue;
using ipc::CPrinter;
using ipc::SharedMemory2;

using namespace middleware;

int main ( int argc, char* argv[] )
{
    std::string releaserName;
    std::string colaRespuesta;


    if (!DSM_ENABLED)
    {
        CPrinter::printErr( "ERROR: EL SERVICIO DSM ESTA APAGADO!" );
		exit ( 0 );
	}

    CPrinter::setHeader( "dsmReleaser" );

    if ( argc != 2 )
    {
        CPrinter::printErr( "Cantidad de argumentos invalidos" );
        exit( 1 );
    }

    releaserName = argv[1];

    CPrinter::setHeader( "dsmReleaser " + releaserName );

    CPrinter::printOut( "INICIADO" );

    MessageQueue<TokenDSM> colaLiberacion =
            MessageQueue<TokenDSM>::get( "/tmp/" + releaserName + "shm.ipc", COLA_LIBERAR_HOST );
    ColaRemotaTransmisor transmisor;

    while ( true )
    {
        std::string colaDestino;
        TokenDSM liberar;

        liberar = colaLiberacion.get( 0 );

        CPrinter::printOut( "Actualizando el token: %d", liberar.idDSM );
        switch ( liberar.idDSM )
        {
            case DSMID_TEST:
            {

                ContadorDistribuido *p = SharedMemory2<ContadorDistribuido>::get( DSM_IPC_BASEFILE, SHM_TEST );
                memcpy( liberar.data, p, sizeof(ContadorDistribuido) );
            }
                break;

            case DSMID_CINTA13A:
            {
                Cinta3Slots *p = SharedMemory2<Cinta3Slots>::get( Cinta13A::s_ipcBaseFile, Cinta13A::s_cintaKey );
                memcpy( liberar.data, p, sizeof(Cinta3Slots) );
            }
                break;

            case DSMID_CINTA13B:
            {
                Cinta3Slots *p = SharedMemory2<Cinta3Slots>::get( Cinta13B::s_ipcBaseFile, Cinta13B::s_cintaKey );
                memcpy( liberar.data, p, sizeof(Cinta3Slots) );
            }
                break;

            case DSMID_CINTA15:
            {
                Cinta5Slots *p = SharedMemory2<Cinta5Slots>::get( Cinta15::s_ipcBaseFile, Cinta15::s_cintaKey );
                memcpy( liberar.data, p, sizeof(Cinta5Slots) );
            }
                break;

            case DSMID_R11APROD:
            {
                bool *p = SharedMemory2<bool>::get( Robot11AProductor::s_ipcBaseFile, Robot11AProductor::s_esperaEspacioKey );
                memcpy( liberar.data, p, sizeof(bool) );
            }
                break;

            case DSMID_R11BPROD:
            {
                bool *p = SharedMemory2<bool>::get( Robot11BProductor::s_ipcBaseFile, Robot11BProductor::s_esperaEspacioKey );
                memcpy( liberar.data, p, sizeof(bool) );
            }
                break;

            case DSMID_R14CONS:
            {
                bool *p = SharedMemory2<bool>::get( Robot14Consumidor::s_ipcBaseFile, Robot14Consumidor::s_esperaProductoKey );
                memcpy( liberar.data, p, sizeof(bool) );
            }
                break;

            case DSMID_R14PROD:
            {
                bool *p = SharedMemory2<bool>::get( Robot14Productor::s_ipcBaseFile, Robot14Productor::s_esperaEspacioKey );
                memcpy( liberar.data, p, sizeof(bool) );
            }
                break;

            case DSMID_R16CONS:
            {
                bool *p = SharedMemory2<bool>::get( Robot16Consumidor::s_ipcBaseFile, Robot16Consumidor::s_esperaProductoKey );
                memcpy( liberar.data, p, sizeof(bool) );
            }
                break;

            case DSMID_PRIMERCINTA_IZQ:
            {
            	CintaProductos *p = SharedMemory2<CintaProductos>::get( middleware::CommunicationPrimerCinta::CINTA_SHMEM_PATH, middleware::CommunicationPrimerCinta::CINTA_SHMEM_KEY_IZQ );
                memcpy( liberar.data, p, sizeof(CintaProductos) );
            }
                break;

            case DSMID_PRIMERCINTA_DER:
            {
            	CintaProductos *p = SharedMemory2<CintaProductos>::get( middleware::CommunicationPrimerCinta::CINTA_SHMEM_PATH, middleware::CommunicationPrimerCinta::CINTA_SHMEM_KEY_DER);
                memcpy( liberar.data, p, sizeof(CintaProductos) );
            }
                break;

            case DSMID_CANASTOS_IZQ:
            {
                MemCanastos *p = SharedMemory2<MemCanastos>::get( middleware::CommunicationCanastos::AGV_SHMEM_CANASTOS_PATH, middleware::CommunicationCanastos::AGV_SHMEM_CANASTOS_KEY_IZQ );
                memcpy( liberar.data, p, sizeof(MemCanastos) );
            }
                break;

            case DSMID_CANASTOS_DER:
            {
                MemCanastos *p = SharedMemory2<MemCanastos>::get( middleware::CommunicationCanastos::AGV_SHMEM_CANASTOS_PATH, middleware::CommunicationCanastos::AGV_SHMEM_CANASTOS_KEY_DER );
                memcpy( liberar.data, p, sizeof(MemCanastos) );
            }
                break;

            case DSMID_CANASTOS_MED:
            {
                MemCanastos *p = SharedMemory2<MemCanastos>::get( middleware::CommunicationCanastos::AGV_SHMEM_CANASTOS_PATH, middleware::CommunicationCanastos::AGV_SHMEM_CANASTOS_KEY_MED );
                memcpy( liberar.data, p, sizeof(MemCanastos) );
            }
                break;

                //----------

            case DSMID_EROBOT11_IZQ:
            {
                EstadoRobotPiezas *p = SharedMemory2<EstadoRobotPiezas>::get( CommunicationRobot11::ROBOT11_SHMEM_PATH, CommunicationRobot11::ROBOT11_SHMEM_KEY_IZQ );
                memcpy( liberar.data, p, sizeof(EstadoRobotPiezas) );
            }
            break;

            case DSMID_EROBOT11_DER:
            {
                EstadoRobotPiezas *p = SharedMemory2<EstadoRobotPiezas>::get( CommunicationRobot11::ROBOT11_SHMEM_PATH, CommunicationRobot11::ROBOT11_SHMEM_KEY_DER );
                memcpy( liberar.data, p, sizeof(EstadoRobotPiezas) );
            }
            break;

            case DSMID_EROBOT12_IZQ:
            {
                EstadoRobotPiezas *p = SharedMemory2<EstadoRobotPiezas>::get( CommunicationRobot12::ROBOT12_SHMEM_PATH,
                        CommunicationRobotPiezas::getAltKey(CommunicationRobot12::ROBOT12_SHMEM_KEY_IZQ));
                memcpy( liberar.data, p, sizeof(EstadoRobotPiezas) );
            }
            break;

            case DSMID_EROBOT12_DER:
            {
                EstadoRobotPiezas *p = SharedMemory2<EstadoRobotPiezas>::get( CommunicationRobot12::ROBOT12_SHMEM_PATH,
                        CommunicationRobotPiezas::getAltKey(CommunicationRobot12::ROBOT12_SHMEM_KEY_DER));
                memcpy( liberar.data, p, sizeof(EstadoRobotPiezas) );
            }
            break;

            case DSMID_LISTOROBOT12_IZQ:
            {
                Robot12Listo *p = SharedMemory2<Robot12Listo>::get( CommunicationRobot12::ROBOT12_SHMEM_PATH, CommunicationRobot12::ROBOT12_SHMEM_KEY_IZQ);
                memcpy( liberar.data, p, sizeof(Robot12Listo) );
            }
            break;

            case DSMID_LISTOROBOT12_DER:
            {
                Robot12Listo *p = SharedMemory2<Robot12Listo>::get( CommunicationRobot12::ROBOT12_SHMEM_PATH, CommunicationRobot12::ROBOT12_SHMEM_KEY_DER);
                memcpy( liberar.data, p, sizeof(Robot12Listo) );
            }
            break;

            case DSMID_EROBOT5:
            {
                EstadoRobot5 *p = SharedMemory2<EstadoRobot5>::get( CommunicationRobot5::R5_SHMEM_PATH, CommunicationRobot5::R5_SHMEM_ESTADO_KEY);
                memcpy( liberar.data, p, sizeof(EstadoRobot5) );
            }
            break;

            case DSMID_PENDROBOT5:
            {
                PendientesRobot5 *p = SharedMemory2<PendientesRobot5>::get( CommunicationRobot5::R5_SHMEM_PATH, CommunicationRobot5::R5_SHMEM_PENDIENTES_KEY);
                memcpy( liberar.data, p, sizeof(PendientesRobot5) );
            }
            break;

                //----------

            default:
                throw Exception( "DSM: Unknown DSMID" );
                break;
        }

        colaDestino = COLA_LIBERAR_BROKER_BASENAME + StringUtils::NumberToString( liberar.idDSM );

        CPrinter::printOut( "Devolviendo el token %d al broker por la cola: %s", liberar.idDSM,colaDestino.c_str() );
        transmisor.enviarMensaje<TokenDSM>( colaDestino, liberar );
    }

    return 0;
}
